using System.Collections.Generic;
using System.Linq;
using DataAccessLayer;

namespace Editor
{
    public class PresenterFacade : IPresenterFacade
    {
        private GameData Model;

        private readonly IBusinessLogicLayer Bll;

        public IGameMenuPresenter GameMenuPresenter { get; private set; }

        public IGameLevelPresenter GameLevelPresenter { get; private set; }

        public IProtagonistPresenter ProtagonistPresenter { get; private set; }

        public IEnemyPresenter EnemyPresenter { get; private set; }

        public IMiniBossPresenter MinibossPresenter { get; private set; }

        public IBossPresenter BossPresenter { get; private set; }

        public IBulletPresenter BulletPresenter { get; private set; }

        public IWeaponPresenter WeaponPresenter { get; private set; }

        public IFighterPodPresenter FighterPodPresenter { get; private set; }

        public IShaderPresenter ShaderPresenter { get; private set; }

        public PresenterFacade()
        {
            Bll = BusinessLogicLayer.UniqueInstance;

            GameMenuPresenter = new GameMenuPresenter(this);
            
            GameLevelPresenter = new GameLevelPresenter(this);
            
            ProtagonistPresenter = new ProtagonistPresenter(this);
            
            EnemyPresenter = new EnemyPresenter(this);
            
            MinibossPresenter = new MiniBossPresenter(this);
            
            BossPresenter = new BossPresenter(this);
            
            BulletPresenter = new BulletPresenter(this);
            
            WeaponPresenter = new WeaponPresenter(this);
            
            FighterPodPresenter = new FighterPodPresenter(this);
            
            ShaderPresenter = new ShaderPresenter(this);
        }

        public EditorStartData LoadApplicationData(string filename)
        {
            EditorStartData startData = Bll.LoadApplicationData(filename);
            Model = startData.GameData;

            GameMenuPresenter.Model = Model.Menus;

            GameLevelPresenter.Model = Model.Levels;

            ProtagonistPresenter.Model = Model.Protagonists;

            EnemyPresenter.Model = Model.Enemies;

            MinibossPresenter.Model = Model.MiniBosses;

            BossPresenter.Model = Model.Bosses;

            BulletPresenter.Model = Model.Bullets;

            WeaponPresenter.Model = Model.Weapons;

            FighterPodPresenter.Model = Model.FighterPods;

            ShaderPresenter.Model = Model.Shaders;
            
            return startData;
        }

        public List<WeaponBase> GetWeapons()
        {
            return Model.Weapons;
        }

        public int CreateObjectId()
        {
            int tempId = Model.Menus.Count + Model.Levels.Count + Model.Protagonists.Count +
                         Model.Enemies.Count + Model.MiniBosses.Count + Model.Bosses.Count +
                         Model.Weapons.Count + Model.FighterPods.Count + Model.Shaders.Count + 1;

            return ValidateObjectId(tempId);
        }

        public void SaveGameFile(string filename)
        {
            Bll.SaveGameFile(Model, filename);
        }

        private int ValidateObjectId(int id)
        {
            int idCopy = id;

            if(Model.Menus.Any(menu => menu.ID == idCopy) ||
                Model.Levels.Any(level => level.ID == idCopy ||
                Model.Protagonists.Any(prot => prot.ID == idCopy) ||
                Model.Enemies.Any(enm => enm.ID == idCopy) ||
                Model.MiniBosses.Any(mb => mb.ID == idCopy) ||
                Model.Bosses.Any(b => b.ID == idCopy) ||
                Model.Weapons.Any(w => w.ID == idCopy) ||
                Model.FighterPods.Any(fp => fp.ID == idCopy) ||
                Model.Shaders.Any(s => s.ID == idCopy)))
            {
                ValidateObjectId(++id);
            }

            return id;
        }
    }
}